#ifndef STRUCTS_H
#define STRUCTS_H


#include <Maths/Vector3.h>
#include <vector>
#include <stdlib.h>


struct Vertex
{
    Vertex(Vector3Arg position, Vector3Arg colour)
        : position(position)
        , colour(colour)
    {
    }
    Vector3 position;
    Vector3 colour;
};


struct Quad
{
    Quad(Vector3Arg a, Vector3Arg b, Vector3Arg c, Vector3Arg d)
        : a(a), b(b), c(c), d(d)
    {
        n = Normalize(Cross(b - a, c - a));
    }
    Vector3 a, b, c, d;
    Vector3 n;
};


struct Contribution
{
    Contribution(size_t patchIdx, float factor)
        : patchIdx(patchIdx)
        , factor(factor)
    {
    }
    Contribution(const Contribution& other)
        : patchIdx(other.patchIdx)
        , factor(other.factor)
    {
    }
    size_t patchIdx;
    float factor;
};


struct Patch
{

    Patch()
    {
        Init(Vector3::kZero, Vector3::kZero, Vector3::kZero, 0);
    }

    Patch(Vector3Arg position, Vector3Arg normal, float area)
    {
        Init(Vector3::kZero, position, normal, area);
    }

    Patch(Vector3 albedo, Vector3 position, Vector3 normal, float area)
    {
        Init(albedo, position, normal, area);
    }

    void Init(Vector3 albedo, Vector3 position, Vector3 normal, float area)
    {
        this->albedo = albedo;
        this->position = position;
        this->normal = normal;
        this->direct = Vector3::kZero;
        this->indirect = Vector3::kZero;
        this->debugColour = Vector3((float)rand()/(float)RAND_MAX, (float)rand()/(float)RAND_MAX, (float)rand()/(float)RAND_MAX);
        this->area = area;
        this->parent = NULL;
    }


    Vector3 albedo;
    Vector3 position;
    Vector3 normal;
    Vector3 direct;
    Vector3 indirect;
    Vector3 debugColour;
    float area;
    Patch* parent;
    std::vector<size_t> children;
    std::vector<Contribution> contributions;
};


struct ContributionDebug
{
    ContributionDebug(size_t patchIndex, const Contribution& contribution)
        : patchIndex(patchIndex)
        , contribution(contribution)
    {
    }
    size_t patchIndex;
    Contribution contribution;
};


#endif
